﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если ОбщегоНазначения.ИнформационнаяБазаФайловая() И Параметры.ЗапрашиватьПараметрыАдминистрированияКластера Тогда
		ВызватьИсключение НСтр("ru = 'Настройка параметров кластера серверов доступна только в клиент-серверном режиме работы.'");
	КонецЕсли;
	
	Если Параметры.ЗапрашиватьПараметрыАдминистрированияКластера
		И ОбщегоНазначения.ЭтоMacOSКлиент() Тогда
		Возврат; // Отказ устанавливается в ПриОткрытии.
	КонецЕсли;
	
	ДоступноИспользованиеРазделенныхДанных = ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных();
	
	Если Параметры.ПараметрыАдминистрирования = Неопределено Тогда
		ПараметрыАдминистрирования = СтандартныеПодсистемыСервер.ПараметрыАдминистрирования();
	Иначе
		ПараметрыАдминистрирования = Параметры.ПараметрыАдминистрирования;
	КонецЕсли;
	
	ПроверитьНеобходимостьВводаПараметровАдминистрирования();
	
	Если ДоступноИспользованиеРазделенныхДанных Тогда
		
		ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(
		ПараметрыАдминистрирования.ИмяАдминистратораИнформационнойБазы);
		Если ПользовательИБ <> Неопределено Тогда
			ИдентификаторАдминистратораИБ = ПользовательИБ.УникальныйИдентификатор;
		КонецЕсли;
		Пользователи.НайтиНеоднозначныхПользователейИБ(Неопределено, ИдентификаторАдминистратораИБ);
		АдминистраторИБ = Справочники.Пользователи.НайтиПоРеквизиту("ИдентификаторПользователяИБ", ИдентификаторАдминистратораИБ);
		
	КонецЕсли;
	
	Если Не ПустаяСтрока(Параметры.Заголовок) Тогда
		Заголовок = Параметры.Заголовок;
	КонецЕсли;
	
	Если ПустаяСтрока(Параметры.ПоясняющаяНадпись) Тогда
		Элементы.ПоясняющаяНадпись.Видимость = Ложь;
	Иначе
		Элементы.ПоясняющаяНадпись.Заголовок = Параметры.ПоясняющаяНадпись;
	КонецЕсли;
	
	ЗаполнитьЗначенияСвойств(ЭтотОбъект, ПараметрыАдминистрирования);
	
	Элементы.РежимРаботы.ТекущаяСтраница = ?(ДоступноИспользованиеРазделенныхДанных, Элементы.РазделенныйРежим, Элементы.НеразделенныйРежим);
	Элементы.ГруппаАдминистрированиеИБ.Видимость = Параметры.ЗапрашиватьПараметрыАдминистрированияИБ;
	Элементы.ГруппаАдминистрированиеКластера.Видимость = Параметры.ЗапрашиватьПараметрыАдминистрированияКластера;
	
	Если ОбщегоНазначения.ЭтоLinuxКлиент() Тогда
		
		ТипПодключения = "RAS";
		Элементы.ТипПодключения.Видимость = Ложь;
		Элементы.ГруппаПараметрыУправления.ОтображатьЗаголовок = Истина;
		Элементы.ГруппаПараметрыУправления.Отображение = ОтображениеОбычнойГруппы.СлабоеВыделение;
		
	КонецЕсли;
	
	Элементы.ГруппаТипПодключения.ТекущаяСтраница = ?(ТипПодключения = "COM", Элементы.ГруппаCOM, Элементы.ГруппаRAS);
	
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Если Параметры.ЗапрашиватьПараметрыАдминистрированияКластера
		И ОбщегоНазначенияКлиент.ЭтоMacOSКлиент() Тогда
		Отказ = Истина;
		ТекстСообщения = НСтр("ru = 'Подключение к кластеру серверов недоступно в клиенте под управлением ОС X.'");
		ПоказатьПредупреждение(,ТекстСообщения);
		Возврат;
	КонецЕсли;
	
	Если Не ТребуетсяВводПараметровАдминистрирования Тогда
		Попытка
			ПроверитьПараметрыАдминистрирования(ПараметрыАдминистрирования);
		Исключение
			Возврат; // Обработка не требуется. Форма будет открыта в штатном режиме.
		КонецПопытки;
		Отказ = Истина;
		ВыполнитьОбработкуОповещения(ОписаниеОповещенияОЗакрытии, ПараметрыАдминистрирования);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)
	
	Если Не Параметры.ЗапрашиватьПараметрыАдминистрированияИБ Тогда
		Возврат;
	КонецЕсли;
	
	Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		
		Если Не ЗначениеЗаполнено(АдминистраторИБ) Тогда
			Возврат;
		КонецЕсли;
		
		ИмяПоля = "АдминистраторИБ";
		
		ПользовательИБ = Неопределено;
		ПолучитьАдминистратораИБ(ПользовательИБ);
		Если ПользовательИБ = Неопределено Тогда
			ОбщегоНазначения.СообщитьПользователю(НСтр("ru = 'Указанный пользователь не имеет доступа к информационной базе.'"),,
				ИмяПоля,,Отказ);
			Возврат;
		КонецЕсли;
		
		Если Не Пользователи.ЭтоПолноправныйПользователь(ПользовательИБ, Истина) Тогда
			ОбщегоНазначения.СообщитьПользователю(НСтр("ru = 'У пользователя нет административных прав.'"),,
				ИмяПоля,,Отказ);
			Возврат;
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ТипПодключенияПриИзменении(Элемент)
	
	Элементы.ГруппаТипПодключения.ТекущаяСтраница = ?(ТипПодключения = "COM", Элементы.ГруппаCOM, Элементы.ГруппаRAS);
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура Записать(Команда)
	
	ОчиститьСообщения();
	
	Если Не ПроверитьЗаполнениеНаСервере() Тогда
		Возврат;
	КонецЕсли;
	
	// Заполняем структуру настроек.
	ЗаполнитьЗначенияСвойств(ПараметрыАдминистрирования, ЭтотОбъект);
	
	ПроверитьПараметрыАдминистрирования(ПараметрыАдминистрирования);
	
	СохранитьПараметрыПодключения();
	
	// Восстанавливаем значения паролей.
	ЗаполнитьЗначенияСвойств(ПараметрыАдминистрирования, ЭтотОбъект);
	
	Закрыть(ПараметрыАдминистрирования);
	
КонецПроцедуры

&НаКлиенте
Процедура Отмена(Команда)
	Закрыть();
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервере
Функция ПроверитьЗаполнениеНаСервере()
	
	Возврат ПроверитьЗаполнение();
	
КонецФункции

&НаСервере
Процедура СохранитьПараметрыПодключения()
	
	// Сохраняем параметры в константу, пароли очищаем.
	СтандартныеПодсистемыСервер.УстановитьПараметрыАдминистрирования(ПараметрыАдминистрирования);
	
КонецПроцедуры

&НаСервере
Процедура ПолучитьАдминистратораИБ(ПользовательИБ = Неопределено)
	
	Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		Если ЗначениеЗаполнено(АдминистраторИБ) Тогда
			ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(
				ОбщегоНазначения.ЗначениеРеквизитаОбъекта(АдминистраторИБ, "ИдентификаторПользователяИБ"));
		Иначе
			ПользовательИБ = Неопределено;
		КонецЕсли;
		ИмяАдминистратораИнформационнойБазы = ?(ПользовательИБ = Неопределено, "", ПользовательИБ.Имя);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьПараметрыАдминистрирования(ПараметрыАдминистрирования)
	
	Если ОбщегоНазначенияКлиент.ИнформационнаяБазаФайловая()
		И ТипПодключения = "COM" Тогда
		
		Оповещение = Новый ОписаниеОповещения("ПроверитьПараметрыАдминистрированияПослеПроверкиCOMСоединителя", ЭтотОбъект);
		ОбщегоНазначенияКлиент.ЗарегистрироватьCOMСоединитель(Ложь, Оповещение);
	Иначе 
		ПроверитьПараметрыАдминистрированияПослеПроверкиCOMСоединителя(Истина, Неопределено);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьПараметрыАдминистрированияПослеПроверкиCOMСоединителя(Зарегистрировано, Контекст) Экспорт
	
	Если Зарегистрировано Тогда 
		ПроверитьПараметрыАдминистрированияНаСервере();
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПроверитьПараметрыАдминистрированияНаСервере()
	
	Если ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда
		ПроверитьПараметрыАдминистрированияФайловойБазы();
	Иначе 
		АдминистрированиеКластера.ПроверитьПараметрыАдминистрирования(ПараметрыАдминистрирования,,
			Параметры.ЗапрашиватьПараметрыАдминистрированияКластера, Параметры.ЗапрашиватьПараметрыАдминистрированияИБ);
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПроверитьНеобходимостьВводаПараметровАдминистрирования()
	
	ТребуетсяВводПараметровАдминистрирования = Истина;
	
	Если Параметры.ЗапрашиватьПараметрыАдминистрированияИБ И Не Параметры.ЗапрашиватьПараметрыАдминистрированияКластера Тогда
		
		КоличествоПользователей = ПользователиИнформационнойБазы.ПолучитьПользователей().Количество();
		
		Если КоличествоПользователей > 0 Тогда
			
			// Вычисляем актуальное имя пользователя, даже если оно было ранее изменено в текущем сеансе;
			// Например, для подключения к текущей ИБ через внешнее соединение из этого сеанса;
			// Во всех остальных случаях достаточно получить ПользователиИнформационнойБазы.ТекущийПользователь().
			ТекущийПользователь = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(
				ПользователиИнформационнойБазы.ТекущийПользователь().УникальныйИдентификатор);
			
			Если ТекущийПользователь = Неопределено Тогда
				ТекущийПользователь = ПользователиИнформационнойБазы.ТекущийПользователь();
			КонецЕсли;
			
			Если ТекущийПользователь.АутентификацияСтандартная И Не ТекущийПользователь.ПарольУстановлен 
				И Пользователи.ЭтоПолноправныйПользователь(ТекущийПользователь, Истина) Тогда
				
				ПараметрыАдминистрирования.ИмяАдминистратораИнформационнойБазы = ТекущийПользователь.Имя;
				ПараметрыАдминистрирования.ПарольАдминистратораИнформационнойБазы = "";
				
				ТребуетсяВводПараметровАдминистрирования = Ложь;
				
			КонецЕсли;
			
		ИначеЕсли КоличествоПользователей = 0 Тогда
			
			ПараметрыАдминистрирования.ИмяАдминистратораИнформационнойБазы = "";
			ПараметрыАдминистрирования.ПарольАдминистратораИнформационнойБазы = "";
			
			ТребуетсяВводПараметровАдминистрирования = Ложь;
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ПроверитьПараметрыАдминистрированияФайловойБазы()
	
	Если Параметры.ЗапрашиватьПараметрыАдминистрированияИБ Тогда
		
		// В базовых версиях проверку подключения не осуществляем.
		Если СтандартныеПодсистемыСервер.ЭтоБазоваяВерсияКонфигурации() 
			Или СтандартныеПодсистемыСервер.ЭтоУчебнаяПлатформа() Тогда
			Возврат;
		КонецЕсли;
		
		ПараметрыПодключения = ОбщегоНазначенияКлиентСервер.СтруктураПараметровДляУстановкиВнешнегоСоединения();
		ПараметрыПодключения.КаталогИнформационнойБазы = СтрРазделить(СтрокаСоединенияИнформационнойБазы(), """")[1];
		ПараметрыПодключения.ИмяПользователя = ИмяАдминистратораИнформационнойБазы;
		ПараметрыПодключения.ПарольПользователя = ПарольАдминистратораИнформационнойБазы;
		
		Результат = ОбщегоНазначения.УстановитьВнешнееСоединениеСБазой(ПараметрыПодключения);
		
		Если Результат.Соединение = Неопределено Тогда
			ВызватьИсключение Результат.КраткоеОписаниеОшибки;
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти